


#region Libraries
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using MediaCenter;
#endregion

namespace MC_CSPlugin
{
    #region Interop Program ID Registration
    //The interop services allow the plugin to be registered with a CLSID so Media Center
    //Can find it
    //The Prog ID must match with that in the registry in order for 
    //MC to be able to pick up the plugin
    [System.Runtime.InteropServices.ProgId ( "MC_CSPlugin.YARS" )]
    #endregion
    public partial class MainInterface : UserControl
    {
        #region Attributes

        public MediaCenter.MCAutomation mcRef;

        #endregion

        #region Constructor

        public MainInterface()
        {
            InitializeComponent();
        }
        #endregion

        #region Media Center Initialisation

        // Set all Components on the Panel to invisible
        private void setVisibility(Control ctlControl, Boolean blnVisible)
        {
            while (ctlControl != null)
            {
                ctlControl.Visible = blnVisible;

                ctlControl = mainPanel.GetNextControl(ctlControl, true);
            }
        }

        // Check the version of Media Center.
        // Don't support C# Plugins with versions lower than 11.1
        // Certain Events are not supported with older versions
        private Boolean checkVersion()
        {
            IMJVersionAutomation version;

            version = mcRef.GetVersion();

            if (version.Major >= 12 && version.Minor >= 0 && version.Build >= 213)
            {
                return true;
            }

            setVisibility(Panel, false);

            Panel.Visible = true;
            txtUserInfo.Visible = true;

            addUserInfoText("YARS only works for MC 12.0.213 and up");

            return false;
        }

        public void Init(MediaCenter.MCAutomation mcRef)
        {
            try
            {
                // This is the main entry for MC Automation
                this.mcRef = mcRef;
                // Check the version we're running in
                if (checkVersion())
                {
                    // Tell MC to call our MJEvent Routine in case of evenst
                    this.mcRef.FireMJEvent += new IMJAutomationEvents_FireMJEventEventHandler(MJEvent);
                    // Init our plugin
                    initAll();

                    addUserInfoText("Plugin Initiated");

                    //todo: make configurable
                    String port = "18887";

                    string[] jsonPrefixes = new string[1];
                    jsonPrefixes[0] = "http://+:" + port + "/json/";
                    new JsonServer(this, jsonPrefixes);


                    string[] prefixes = new string[1];
                    prefixes[0] = "http://+:" + port + "/";
                    new StaticServer(this, prefixes);
                }
            }
            catch (Exception e)
            {
                errorHandler(e);
            }
        }

        private void initAll()
        {
            try
            {
                // Set some skin colors
                setSkinColors();
            }
            catch (Exception e)
            {
                errorHandler(e);
            }
        }

        #endregion

        #region ErrorHandler
        private void errorHandler(Exception e)
        {
            addUserInfoText("A Fatal error has occured: " + e.Message);
            addUserInfoText("The Failure Occured In Class Object: " + e.Source);
            addUserInfoText("when calling Method " + e.TargetSite);
            addUserInfoText("The following Inner Exception was caused" + e.InnerException);
            addUserInfoText("The Stack Trace Follows:\r\n" + e.StackTrace);

            txtUserInfo.Dock = DockStyle.Fill;

            this.Enabled = false;
        }
        #endregion

        #region Setting Skin Colors

        private void skinPlugin()
        {
            try
            {
                // MC 12 does not support skinning of C# plugins
                // We do some pseudo skinning by setting the colors used in the skin
                setSkinColors();
            }
            catch (Exception e)
            {
                errorHandler(e);
            }
        }

        // Get the Color for an item and attribute (i.e. "Tree", "BackColor"
        // Look in the wiki for the Metamorphis subject for Items and Attributes
        // http://wiki.jrmediacenter.com/index.php/Metamorphis
        private Color getColor(String strItem, String strAttribute)
        {
            Color colReturned = Color.LightGray;
            int intColor;
            int intR;
            int intG;
            int intB;

            try
            {
                intColor = mcRef.GetSkinInfo(strItem, strAttribute);

                // The color is represented as an int in MC. 
                // Windows requires a ARGB Color object
                // Using bitshifting and masking to get the R, G and B values
                if (intColor != -1)
                {
                    intR = intColor & 255;
                    intG = (intColor >> 8) & 255;
                    intB = (intColor >> 16) & 255;

                    colReturned = Color.FromArgb(intR, intG, intB);
                }
            }
            catch (Exception e)
            {
                errorHandler(e);
            }

            return colReturned;
        }

        // Setting the Backcolor of a Control (if different)
        private void setBackColor(Control control, Color color)
        {
            if (!control.BackColor.Equals(color))
            {
                control.BackColor = color;
            }
        }

        // Setting the Forecolor of a Control (if different)
        private void setForeColor(Control control, Color color)
        {
            if (!control.ForeColor.Equals(color))
            {
                control.ForeColor = color;
            }
        }

        // Setting the Fore- and Backcolors of all Controls (if different)
        private void setAllColors(Control control)
        {
            while (control != null)
            {
                setBackColor(control, getColor("Tree", "BackColor"));
                setForeColor(control, getColor("Tree", "TextColor"));

                control = mainPanel.GetNextControl(control, true);
            }
        }

        // Setting the Color for Maininterface
        private void setMainInterfaceColors()
        {
            this.BackColor = getColor("Tree", "BackColor");
            this.ForeColor = getColor("Tree", "TextColor");
        }

        // Pseude Skin our Plugin
        private void setSkinColors()
        {
            try
            {
                setMainInterfaceColors();
                setAllColors(Panel);
            }
            catch (Exception e)
            {
                errorHandler(e);
            }
        }

        #endregion

        #region Event Handling

        // Just for debugging purposes. Fill a text in the txtUserInfo Textbox
        public void addUserInfoText(String strText)
        {
            txtUserInfo.Text = txtUserInfo.Text + strText + "\r\n";
            txtUserInfo.SelectionStart = txtUserInfo.Text.Length;
            txtUserInfo.ScrollToCaret();
        }

        // This routine is called by MC in case of an Event
        // s1 - String containing the the MC Command.
        // s2 - String containing the the MC Event
        // s3 - String containing supplement information for the Event (not always filled)
        private void MJEvent(String strCommand, String strEvent, String strEventInfo)
        {
            // Debug info
            addUserInfoText(strCommand + "/" + strEvent + "/" + strEventInfo);

            switch (strCommand)
            {
                case "MJEvent type: MCCommand":
                    switch (strEvent)
                    {
                        case "MCC: NOTIFY_TRACK_CHANGE":
                            // Your code goes here
                            break;

                        case "MCC: NOTIFY_PLAYERSTATE_CHANGE":
                            // Your code goes here
                            break;

                        case "MCC: NOTIFY_PLAYLIST_ADDED":
                            // Your code goes here
                            break;

                        case "MCC: NOTIFY_PLAYLIST_INFO_CHANGED":
                            // Your code goes here
                            break;

                        case "MCC: NOTIFY_PLAYLIST_FILES_CHANGED":
                            // Your code goes here
                            break;

                        case "MCC: NOTIFY_PLAYLIST_REMOVED":
                            // Your code goes here
                            break;

                        case "MCC: NOTIFY_PLAYLIST_COLLECTION_CHANGED":
                            // Your code goes here
                            break;

                        case "MCC: NOTIFY_PLAYLIST_PROPERTIES_CHANGED":
                            // Your code goes here
                            break;

                        case "MCC: NOTIFY_SKIN_CHANGED":
                            skinPlugin();
                            break;
                    }

                    break;

                default:
                    break;
            }
        }

        // At the time this template was created the MCC: NOTIFY_SKIN_CHANGED
        // Event didn't function correctly. Doing it on a PAINT Event from Windows.
        private void mainPanel_Paint(object sender, PaintEventArgs e)
        {
            skinPlugin();
        }

        #endregion
    }
}